<script>
const domUtil = require('wind-dom')
import { triggerNativeEvent } from '../utils/event'
import { support, emulateTransitionEnd } from '../utils/vendor'
const emptyArray = []

export default {

  props: {
    images: {
      type: Array,
      default: []
    },
    interval: {
      type: Number,
      default: 5000
    },
    transitionDuration: {
      type: Number,
      default: 600
    },
    onPause: {
      type: String,
      default: 'hover'
    }
  },

  computed: {
    indicators() {
      return this.$el.querySelector('.carousel-indicators')
    }
  },

  mounted() {
    if (!!this.interval) {
      this.pause().cycle()
    }
  },

  beforeDestroy () {
    this.stopper = clearInterval(this.stopper)
  },

  methods: {

    pause(e) {
      e || (this.paused = true)

      if (support.transition) {
        triggerNativeEvent(this.$el, support.transition.end)
        this.cycle(true)
      }

      this.stopper = clearInterval(this.stopper)

      return this
    },

    cycle(e) {
      e || (this.paused = false)

      this.stopper && clearInterval(this.stopper)

      this.interval
        && !this.paused
        && (this.stopper = setInterval(this.next.bind(this), this.interval))

      return this
    },

    next() {
      if (this.sliding) return
      return this.slide('next')
    },

    prev() {
      if (this.sliding) return
      return this.slide('prev')
    },

    slide (type, nextItem) {
      const active = this.$el.querySelector('.item.active')
      const next = nextItem || this.getItemForDirection(type, active)
      const isCycling = this.stopper
      const direction = type === 'next' ? 'left' : 'right'
      const that = this

      if (domUtil.hasClass(next, 'active')) return (this.sliding = false)

      this.sliding = true
      isCycling && this.pause()

      if (!!this.indicators) {
        let activeIndicator = this.indicators.querySelector('.active')
        domUtil.removeClass(activeIndicator, 'active')
        let nextIndicator = this.indicators.children[this.getItemIndex(next)]
        nextIndicator && domUtil.addClass(nextIndicator, 'active')
      }

      if (support.transition && domUtil.hasClass(this.$el, 'slide')) {
        domUtil.addClass(next, type)
        next.offsetWidth  // force reflow
        domUtil.addClass(active, direction)
        domUtil.addClass(next, direction)
        domUtil.once(active, support.transition.end, function() {
          domUtil.removeClass(next, [type, direction].join(' '))
          domUtil.addClass(next, 'active')
          domUtil.removeClass(active, ['active', direction].join(' '))
          that.sliding = false
        })
        emulateTransitionEnd(active, that.transitionDuration)
      } else {
        domUtil.removeClass(active, 'active')
        domUtil.addClass(next, 'active')
        this.sliding = false
      }

      isCycling && this.cycle()

      return this
    },

    to(e) {
      const slideTo = parseInt(e.target.getAttribute('data-slide-to'), 10)
      const activeIndex = this.getItemIndex(this.active = this.$el.querySelector('.active.item'))

      if (slideTo > (this.items.length - 1) || slideTo < 0) return

      // handle the sliding situation violently
      if (this.sliding) return
      if (activeIndex === slideTo) return this.pause().cycle()

      return this.slide(slideTo > activeIndex ? 'next' : 'prev', this.items[slideTo])
    },

    getItemIndex(item) {
      this.items = emptyArray.slice.call(item.parentNode.querySelectorAll('.item'))
      return this.items.indexOf(item || this.active)
    },

    getItemForDirection(direction, active) {
      let activeIndex = this.getItemIndex(active)
      let willWrap = (direction === 'prev' && activeIndex === 0)
                  || (direction === 'next' && activeIndex === (this.items.length - 1))
      if (willWrap && this.wrap) return active
      let delta = direction === 'prev' ? -1 : 1
      let itemIndex = (activeIndex + delta) % this.items.length
      return this.items[itemIndex]
    }

  }
}
</script>

<template>
  <div class="carousel slide" @mouseenter="pause" @mouseleave="cycle">
    <ol class="carousel-indicators">
      <li v-for="(image, index) in images"
        :data-slide-to="index"
        :class="{ 'active': index === 0 }"
        @click="to">
      </li>
    </ol>

    <div class="carousel-inner">
      <div v-for="(image, index) in images" :class="{ 'active': index === 0, 'item': index >= 0 }">
        <a v-if="image.link" :href="image.link" target="_blank">
          <img :src="image.imgSrc">
        </a>
        <img v-else :src="image.imgSrc">
      </div>
    </div>
  </div>
</template>

<style>
@import '../../static/styles/carousel.css';
</style>